from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.model_selection import train_test_split
import numpy as np
import sys
import os
import tensorflow as tf
from tensorflow.keras import layers, optimizers, losses, metrics

np.random.seed(777)
tf.random.set_seed(777)

alpha = 0.001
batch_size = 32
n_epochs = 10

# 2.使用sklearn配合tensorflow2.0+keras接口完成多分类处理（20分）
# (1)Sklearn处理
# ①加载鸢尾花数据集，进行相对处理（6分）
x, y = load_iris(return_X_y=True)

# ④将标签数据进行独热（6分）
enc = OneHotEncoder()
y = enc.fit_transform(y.reshape([-1, 1])).A  # ATTENTION .A or .toarray()
_, n_cls = y.shape

# ②合理进行特征缩放（6分）
scaler = StandardScaler()
x = scaler.fit_transform(x)

# ③切分训练集与测试集，比例自拟（6分）
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=777, train_size=0.8)
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, random_state=777, train_size=0.75)
m_train, n = x_train.shape
print(m_train, n, n_cls)

# (2)模型创建
model = tf.keras.Sequential()

# ①添加一个隐藏层，神经元数量为10（6分）
# ②隐藏层使用relu激活（6分）
model.add(layers.Dense(200, input_dim=n, activation=tf.nn.relu))  # 为了更好的效果，神经元数量改为200
model.add(layers.Dense(n_cls, activation=tf.nn.softmax))

# ③参数可视化（6分）
model.summary()

# ④进行编译，优化器选择Adam优化器（6分）
model.compile(
    optimizer=optimizers.Adam(learning_rate=alpha),
    loss=losses.categorical_crossentropy,
    metrics=[metrics.categorical_accuracy]
)

# ⑤使用训练集数据训练，自定义训练次数（6分）
history = model.fit(x_train, y_train,
          batch_size=batch_size, epochs=n_epochs,
          validation_data=(x_val, y_val))

# (3)模型预测
# ①计算测试集数据的准确率（6分）
r = model.evaluate(x_test, y_test)
print(f'测试集数据的准确率: {r[1]}')
